<template>
  <el-dialog
    title="结构变更管理"
    v-model="dialogVisible"
    width="80%"
       :modal="true"
    :append-to-body="true"
    :lock-scroll="true"
    destroy-on-close
    class="change-dialog"
  >
    <div class="change-container" v-loading="loading">
      <div class="toolbar">
        <el-button-group>
          <el-button type="primary" @click="fetchChanges">
            <el-icon><Refresh /></el-icon> 刷新
          </el-button>
          <el-button type="success" @click="handleCheckStructure">
            <el-icon><Search /></el-icon> 检查变更
          </el-button>
          <el-button type="warning" @click="handleApplyChanges" :disabled="!hasApproved">
            <el-icon><Check /></el-icon> 应用变更
          </el-button>
        </el-button-group>

        <el-radio-group v-model="filterStatus" @change="fetchChanges">
          <el-radio-button label="all">全部</el-radio-button>
          <el-radio-button label="pending">待审核</el-radio-button>
          <el-radio-button label="approved">已批准</el-radio-button>
          <el-radio-button label="rejected">已拒绝</el-radio-button>
          <el-radio-button label="applied">已应用</el-radio-button>
        </el-radio-group>
      </div>

      <el-table
        :data="changeList"
        border
        style="width: 100%"
        height="calc(100% - 50px)"
        row-key="id"
      >
        <el-table-column type="expand">
          <template #default="scope">
            <div class="change-detail">
              <el-row v-if="scope.row.change_sql">
                <el-col :span="24">
                  <h4 class="detail-title">变更SQL</h4>
                  <el-input
                    type="textarea"
                    :rows="3"
                    v-model="scope.row.change_sql"
                    readonly
                  />
                </el-col>
              </el-row>

              <el-row v-if="scope.row.preview_data" style="margin-top: 15px;">
                <el-col :span="24">
                  <h4 class="detail-title">数据预览</h4>
                  <el-table
                    :data="scope.row.preview_data.slice(0, 5)"
                    border
                    stripe
                    size="small"
                    style="width: 100%"
                  >
                    <el-table-column
                      v-for="column in getPreviewColumns(scope.row.preview_data)"
                      :key="column"
                      :prop="column"
                      :label="column"
                      min-width="150"
                    />
                  </el-table>
                </el-col>
              </el-row>
            </div>
          </template>
        </el-table-column>

        <el-table-column label="变更ID" prop="id" width="120" />

        <el-table-column label="变更类型" prop="change_type" width="120">
          <template #default="scope">
            <el-tag :type="getChangeTypeTagType(scope.row.change_type)">
              {{ getChangeTypeLabel(scope.row.change_type) }}
            </el-tag>
          </template>
        </el-table-column>

        <el-table-column label="对象" prop="object_name" min-width="150" />

        <el-table-column label="描述" prop="description" min-width="200" show-overflow-tooltip />

        <el-table-column label="检测时间" prop="detected_at" width="180" />

        <el-table-column label="状态" prop="status" width="100">
          <template #default="scope">
            <el-tag :type="getStatusTagType(scope.row.status)">
              {{ getStatusLabel(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>

        <el-table-column label="操作" width="180" fixed="right">
          <template #default="scope">
            <div class="action-buttons">
              <el-button
                v-if="scope.row.status === 'pending'"
                type="success"
                link
                @click="handleApprove(scope.row)"
              >
                批准
              </el-button>
              <el-button
                v-if="scope.row.status === 'pending'"
                type="danger"
                link
                @click="handleReject(scope.row)"
              >
                拒绝
              </el-button>
              <el-button
                v-if="scope.row.status === 'approved'"
                type="warning"
                link
                @click="handleApplySingle(scope.row)"
              >
                应用
              </el-button>
              <el-button
                v-if="scope.row.status === 'rejected'"
                type="primary"
                link
                @click="handleReconsider(scope.row)"
              >
                重新审核
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-container">
        <el-pagination
          v-model:current-page="pagination.currentPage"
          v-model:page-size="pagination.pageSize"
          :total="pagination.total"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, computed, defineProps, defineEmits, watch, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Refresh, Search, Check } from '@element-plus/icons-vue'
import { getDatasetChanges, checkDatasetStructure, applyDatasetChanges, updateChangeStatus } from '@/api/dataset'

const props = defineProps({
  modelValue: Boolean,
  datasetId: [String, Number]
})

const emit = defineEmits(['update:modelValue'])

// 对话框可见性
const dialogVisible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})

// 状态
const loading = ref(false)
const changeList = ref([])
const filterStatus = ref('all')

// 分页信息
const pagination = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0
})

// 是否有已批准的变更
const hasApproved = computed(() => {
  return changeList.value.some(change => change.status === 'approved')
})

// 获取变更类型标签
const getChangeTypeLabel = (type) => {
  const typeMap = {
    'add_table': '添加表',
    'drop_table': '删除表',
    'rename_table': '重命名表',
    'add_column': '添加列',
    'drop_column': '删除列',
    'modify_column': '修改列',
    'rename_column': '重命名列',
    'add_index': '添加索引',
    'drop_index': '删除索引'
  }
  return typeMap[type] || type
}

// 获取变更类型标签样式
const getChangeTypeTagType = (type) => {
  const typeMap = {
    'add_table': 'success',
    'drop_table': 'danger',
    'rename_table': 'warning',
    'add_column': 'success',
    'drop_column': 'danger',
    'modify_column': 'warning',
    'rename_column': 'warning',
    'add_index': 'info',
    'drop_index': 'info'
  }
  return typeMap[type] || 'info'
}

// 获取状态标签
const getStatusLabel = (status) => {
  const statusMap = {
    'pending': '待审核',
    'approved': '已批准',
    'rejected': '已拒绝',
    'applied': '已应用'
  }
  return statusMap[status] || status
}

// 获取状态标签样式
const getStatusTagType = (status) => {
  const typeMap = {
    'pending': 'info',
    'approved': 'success',
    'rejected': 'danger',
    'applied': 'warning'
  }
  return typeMap[status] || 'info'
}

// 获取预览数据的列
const getPreviewColumns = (previewData) => {
  if (!previewData || previewData.length === 0) return []
  return Object.keys(previewData[0])
}

// 获取结构变更列表
const fetchChanges = async () => {
  if (!props.datasetId) return

  loading.value = true
  try {
    const params = {
      status: filterStatus.value !== 'all' ? filterStatus.value : undefined,
      skip: (pagination.currentPage - 1) * pagination.pageSize,
      limit: pagination.pageSize
    }

    const res = await getDatasetChanges(props.datasetId, params)

    if (res && res.items) {
      changeList.value = res.items
      pagination.total = res.total || res.items.length
    } else {
      changeList.value = []
      pagination.total = 0
    }
  } catch (error) {
    console.error('获取结构变更列表失败:', error)
    ElMessage.error('获取结构变更列表失败: ' + (error.message || '未知错误'))
    changeList.value = []
    pagination.total = 0
  } finally {
    loading.value = false
  }
}

// 检查结构变更
const handleCheckStructure = async () => {
  if (!props.datasetId) return

  loading.value = true
  try {
    await checkDatasetStructure(props.datasetId)
    ElMessage.success('结构变更检查完成')
    fetchChanges()
  } catch (error) {
    console.error('检查结构变更失败:', error)
    ElMessage.error('检查结构变更失败: ' + (error.message || '未知错误'))
  } finally {
    loading.value = false
  }
}

// 应用结构变更
const handleApplyChanges = async () => {
  if (!props.datasetId) return

  ElMessageBox.confirm(
    '确定要应用所有已批准的结构变更吗？此操作将对数据库结构进行修改。',
    '警告',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(async () => {
    loading.value = true
    try {
      await applyDatasetChanges(props.datasetId)
      ElMessage.success('结构变更应用成功')
      fetchChanges()
    } catch (error) {
      console.error('应用结构变更失败:', error)
      ElMessage.error('应用结构变更失败: ' + (error.message || '未知错误'))
    } finally {
      loading.value = false
    }
  }).catch(() => {
    ElMessage.info('已取消操作')
  })
}

// 应用单个变更
const handleApplySingle = async (change) => {
  if (!props.datasetId) return

  ElMessageBox.confirm(
    `确定要单独应用该结构变更吗？\n变更类型: ${getChangeTypeLabel(change.change_type)}\n对象: ${change.object_name}`,
    '警告',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(async () => {
    loading.value = true
    try {
      // 目前API不支持单独应用一个变更，这里应用所有已批准的变更
      await applyDatasetChanges(props.datasetId)
      ElMessage.success('结构变更应用成功')
      fetchChanges()
    } catch (error) {
      console.error('应用结构变更失败:', error)
      ElMessage.error('应用结构变更失败: ' + (error.message || '未知错误'))
    } finally {
      loading.value = false
    }
  }).catch(() => {
    ElMessage.info('已取消操作')
  })
}

// 批准变更
const handleApprove = async (change) => {
  if (!props.datasetId) return

  try {
    await updateChangeStatus(props.datasetId, change.id, { status: 'approved' })
    ElMessage.success('已批准变更')
    // 更新本地数据
    const index = changeList.value.findIndex(c => c.id === change.id)
    if (index !== -1) {
      changeList.value[index].status = 'approved'
    }
  } catch (error) {
    console.error('批准变更失败:', error)
    ElMessage.error('批准变更失败: ' + (error.message || '未知错误'))
  }
}

// 拒绝变更
const handleReject = async (change) => {
  if (!props.datasetId) return

  try {
    await updateChangeStatus(props.datasetId, change.id, { status: 'rejected' })
    ElMessage.success('已拒绝变更')
    // 更新本地数据
    const index = changeList.value.findIndex(c => c.id === change.id)
    if (index !== -1) {
      changeList.value[index].status = 'rejected'
    }
  } catch (error) {
    console.error('拒绝变更失败:', error)
    ElMessage.error('拒绝变更失败: ' + (error.message || '未知错误'))
  }
}

// 重新审核
const handleReconsider = async (change) => {
  if (!props.datasetId) return

  try {
    await updateChangeStatus(props.datasetId, change.id, { status: 'pending' })
    ElMessage.success('变更已重新设为待审核状态')
    // 更新本地数据
    const index = changeList.value.findIndex(c => c.id === change.id)
    if (index !== -1) {
      changeList.value[index].status = 'pending'
    }
  } catch (error) {
    console.error('重新审核失败:', error)
    ElMessage.error('重新审核失败: ' + (error.message || '未知错误'))
  }
}

// 分页大小变化
const handleSizeChange = (val) => {
  pagination.pageSize = val
  fetchChanges()
}

// 当前页变化
const handleCurrentChange = (val) => {
  pagination.currentPage = val
  fetchChanges()
}

// 监听datasetId变化
watch(() => props.datasetId, (newVal) => {
  if (newVal && dialogVisible.value) {
    fetchChanges()
  }
})

// 监听对话框可见性变化
watch(dialogVisible, (newVal) => {
  if (newVal && props.datasetId) {
    fetchChanges()
  }
})

// 组件挂载时获取变更列表
onMounted(() => {
  if (props.datasetId && dialogVisible.value) {
    fetchChanges()
  }
})
</script>

<style scoped>
.change-dialog :deep(.el-dialog__body) {
  padding: 0;
  height: calc(80vh - 120px);
}

.change-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 15px;
}

.toolbar {
  margin-bottom: 15px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.change-detail {
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.detail-title {
  margin: 10px 0;
  color: #606266;
  font-weight: bold;
}

.action-buttons {
  display: flex;
  gap: 8px;
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
  margin-top: 16px;
}
</style>
